package managedBean;

import Merlion.CRM.bean.SalesOrderProcessingModuleRemote;
import Merlion.CRM.entity.LineEntryEntity;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseEvent;
import Merlion.FRM.bean.InvoiceAndReceiptBeanRemote;
import Merlion.FRM.entity.InvoiceLineEntryEntity;
import Merlion.util.state.InvoiceAndReceiptState;
import Merlion.util.state.SalesDocumentState;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletException;
import org.primefaces.event.RowEditEvent;

@ManagedBean(name = "InvoiceManagedBean")
@ViewScoped
public class InvoiceManagedBean implements Serializable {

    private Long invoiceId;
    private Long salesOrderId;
    private Double cashInAdvance;
    private Double discountRate;
    private Double totalPrice;
    private Date issueDate;
    private String issueDateString;
    private Date invoiceDueDate;
    private String invoiceDueDateString;
    private int creditTerm = 30;
    private int discountedCreditTerm;
    private Double amountDue;
    private boolean invoiceStatus;
    private String deleteFlag;
    
    private String customerName;
    
    private Calendar calendar = Calendar.getInstance();
    private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MMM/yyyy");
    //private String tDate = dateFormat.format(calendar.getTime());
    
    private InvoiceAndReceiptState selectedInvoice;
    private List<InvoiceAndReceiptState> selectedInvoices;
    private InvoiceAndReceiptState[] selectedInvoicesArray;
    private InvoiceAndReceiptState selectedViewInvoice;
    private boolean editMode;
  
    private Collection<LineEntryEntity> selectedProductList;
    private Collection<InvoiceLineEntryEntity> selectedViewProductList;
    
    private List<SalesDocumentState> salesOrders;
    
    private String paymentMethod;
    private List<String> paymentMethods;
    
    @EJB
    private InvoiceAndReceiptBeanRemote invoiceBean;
    @EJB
    private SalesOrderProcessingModuleRemote sop;

    public InvoiceManagedBean() {
    }
    
    public void initView(PhaseEvent event) {
        System.out.println("**InvoiceManagedBean: initView()");
        
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        if (selectedInvoices == null) {
            selectedInvoices = invoiceBean.viewAllInvoice();
        }
        if (salesOrders == null) {    
            salesOrders = sop.viewApprovedSalesOrders();
        }    
    }

    public void initViewAddInvoice(PhaseEvent event) {
        System.out.println("**InvoiceManagedBean: initViewAddInvoice()");
         
        try {
            FacesContext.getCurrentInstance().getExternalContext().getSession(true);
            salesOrderId = (Long) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("salesOrderId");
            issueDate = (Date) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("issueDate");
            issueDateString = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("issueDateString");
            invoiceDueDate = (Date) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("invoiceDueDate");
            invoiceDueDateString = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("invoiceDueDateString");
            paymentMethod = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("paymentMethod");
            
        if(discountedCreditTerm == 0){
            discountedCreditTerm = (Integer) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("discountedCreditTerm");
        }
        if (customerName == null) {
            customerName = invoiceBean.getCustomerName(salesOrderId);
        }
        if (selectedProductList == null) {
                selectedProductList = invoiceBean.getProductDetails(salesOrderId);
        }
        if (totalPrice == null) {
            totalPrice = invoiceBean.getTotalPrice(salesOrderId);
        }
        if (cashInAdvance == null) {
            cashInAdvance = invoiceBean.getCashInAdvanceAmt(salesOrderId);
            if (getCashInAdvance() != 0.0) {
                invoiceStatus= true;
            } else  {
               invoiceStatus=false;
            }
           invoiceStatus = (Boolean) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("invoiceStatus");
            
        }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public void initViewOutstandingInvoice(PhaseEvent event) {
        System.out.println("**InvoiceManagedBean: initViewOutstandingInvoice()");
        
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        if (selectedInvoices == null) {
            selectedInvoices = invoiceBean.viewOutstandingInvoice();
        }
    }

    public void initViewOverdueInvoice(PhaseEvent event) {
        System.out.println("**InvoiceManagedBean: initViewOverdueInvoice()");
        
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        if (selectedInvoices == null) {
            selectedInvoices = invoiceBean.viewOverdueInvoice();
        }
    }

    public void doSearchInvoice(ActionEvent event) throws IOException {
        System.out.println("**InvoiceManagedBean: doSearchInvoice()");
        
        try {
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("salesOrderId", salesOrderId);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("issueDate", issueDate);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("issueDateString", issueDateString);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("invoiceDueDateString", invoiceDueDateString);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("invoiceDueDate", invoiceDueDate);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("creditTerm", creditTerm);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("discountedCreditTerm", discountedCreditTerm);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("paymentMethod", paymentMethod);
        
        FacesContext.getCurrentInstance().getExternalContext().redirect("addInvoiceConfirmationPage.xhtml");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void doAddInvoice(ActionEvent event) throws IOException {
        System.out.println("**InvoiceManagedBean: doAddInvoice()");
           
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("salesOrderId", salesOrderId);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("customerName", customerName);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("selectedProductList", selectedProductList);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("totalPrice", totalPrice);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("issueDate", issueDate);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("invoiceDueDate", invoiceDueDate);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("creditTerm", creditTerm);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("discountedCreditTerm", discountedCreditTerm);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("cashInAdvance", cashInAdvance);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("paymentMethod", paymentMethod);

        Long invoiceId = invoiceBean.addInvoice(salesOrderId, issueDate, invoiceDueDate, discountedCreditTerm, paymentMethod);
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("invoiceId", invoiceId);

        if (invoiceId != null) {
            System.out.println("**InvoiceManagedBean: New invoice has been sucessfully added.");
            FacesContext.getCurrentInstance().getExternalContext().redirect("SuccessfulAddInvoice.xhtml");
        } else {
            System.out.println("**InvoiceManagedBean: Fail to add new invoice.");
            FacesContext.getCurrentInstance().getExternalContext().redirect("FailAddInvoice.xhtml");
        }
    }

    public void onEditRow(RowEditEvent event) {
        System.out.println("**InvoiceManagedBean: onEditRow()");
        
        InvoiceAndReceiptState irs = (InvoiceAndReceiptState) event.getObject();
        if (irs != null) {
            Long eInvoiceId = irs.getInvoiceId();
            Long eSalesOrderId = irs.getSalesOrderId();
            Double eCashInAdvance = irs.getCashInAdvance();
            Double eDiscountRate = irs.getDiscountRate();
            Double eTotalPrice = irs.getTotalPrice();
            Date eIssueDate = irs.getIssueDate();
            Date eInvoiceDueDate = irs.getInvoiceDueDate();
            int eCreditTerm = irs.getCreditTerm();
            int eDiscountedCreditTerm = irs.getDiscountedCreditTerm();
            Double eAmountDue = irs.getAmountDue();
            boolean eInvoiceStatus = irs.isInvoiceStatus();
            System.out.println("INVOICE STATUS "+eInvoiceStatus);
            String eDeleteFlag = irs.getDeleteFlag();
        
            invoiceBean.editInvoice(eInvoiceId, eSalesOrderId, eCashInAdvance, eDiscountRate, eTotalPrice, 
                    eIssueDate, eInvoiceDueDate, eCreditTerm, eDiscountedCreditTerm, 
                    eAmountDue, eInvoiceStatus, eDeleteFlag);
            System.out.println("**InvoiceManagedBean:  Invoice is successfully edited.");
        } else {
            System.out.println("No invoice id is found. Edit invoice failed.");
        }
    }

    public void doDelete(ActionEvent event) throws IOException {
        System.out.println("**InvoiceManagedBean: doDelete()");
        
        if (getSelectedInvoice() != null) {
            invoiceId = getSelectedInvoice().getInvoiceId();
            invoiceBean.deleteInvoice(invoiceId);
            System.out.println("**InvoiceManagedBean: Deletion is successful.");
        } else {
            System.out.println("**InvoiceManagedBean: Selected invoice data is null.");
        }
        
        FacesContext.getCurrentInstance().getExternalContext().redirect("viewInvoice.xhtml");
    }

    
    
    public void doGenerateDunningLetter(ActionEvent event) throws IOException{
        System.out.println("**InvoiceManagedBean : doGenerateDunningLetter()");
        if(selectedInvoicesArray != null){
            for(InvoiceAndReceiptState i : selectedInvoicesArray){
              invoiceId= i.getInvoiceId();
              invoiceBean.doGenerateDunningLetter(invoiceId);
                //print jasper report
            }
       
        }else{
             System.out.println("**InvoiceManagedBean : fail to create dunning letter");
       
        }
    }
    
    
    public void doDeletes() throws IOException {
        System.out.println("**InvoiceManagedBean: doDeletes()");

        if (selectedInvoicesArray != null) {
            for (InvoiceAndReceiptState i : selectedInvoicesArray) {
                invoiceBean.deleteInvoice(i.getInvoiceId());
                System.out.println("**InvoiceManagedBean: Deletion is successful.");
            }
        } else {
            System.out.println("**InvoiceManagedBean: Selected invoice data is null.");
        }

        FacesContext.getCurrentInstance().getExternalContext().redirect("viewInvoice.xhtml");
    }

    public void doSave(ActionEvent event) throws IOException {
        System.out.println("**InvoiceManagedBean: doSave()");

        Long eInvoiceId = selectedViewInvoice.getInvoiceId();
        Long eSalesOrderId = selectedViewInvoice.getSalesOrderId();
        Double eCashInAdvance = selectedViewInvoice.getCashInAdvance();
        Double eDiscountRate = selectedViewInvoice.getDiscountRate();
        Double eTotalPrice = selectedViewInvoice.getTotalPrice();
        Date eIssueDate = selectedViewInvoice.getIssueDate();
        Date eInvoiceDueDate = selectedViewInvoice.getInvoiceDueDate();
        int eCreditTerm = selectedViewInvoice.getCreditTerm();
        int eDiscountedCreditTerm = selectedViewInvoice.getDiscountedCreditTerm();
        Double eAmountDue = selectedViewInvoice.getAmountDue();
        boolean eInvoiceStatus = selectedViewInvoice.isInvoiceStatus();
        String eDeleteFlag = selectedViewInvoice.getDeleteFlag();
        
        invoiceBean.editInvoice(eInvoiceId, eSalesOrderId, eCashInAdvance, eDiscountRate, eTotalPrice, 
                eIssueDate, eInvoiceDueDate, eCreditTerm, eDiscountedCreditTerm, 
                eAmountDue, eInvoiceStatus, eDeleteFlag);
        System.out.println("**InvoiceManagedBean:  Invoice is successfully edited.");

        FacesContext.getCurrentInstance().getExternalContext().redirect("viewInvoice.xhtml");
    }

    public void doGetPaymentMethods() {
        System.out.println("**InvoiceManagedBean : doGetPaymentMethods()");

        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        if (paymentMethods == null) {
            
            paymentMethods = invoiceBean.getPaymentMethods(salesOrderId);
            System.out.println(paymentMethods);
            this.setPaymentMethods(paymentMethods);
        }
    }

    public Double getAmountDue() {
        return amountDue;
    }

    public void setAmountDue(Double amountDue) {
        this.amountDue = amountDue;
    }

    public Calendar getCalendar() {
        return calendar;
    }

    public void setCalendar(Calendar calendar) {
        this.calendar = calendar;
    }

    public Double getCashInAdvance() {
        return cashInAdvance;
    }

    public void setCashInAdvance(Double cashInAdvance) {
        this.cashInAdvance = cashInAdvance;
    }

    public int getCreditTerm() {
        return creditTerm;
    }

    public void setCreditTerm(int creditTerm) {
        this.creditTerm = creditTerm;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public SimpleDateFormat getDateFormat() {
        return dateFormat;
    }

    public void setDateFormat(SimpleDateFormat dateFormat) {
        this.dateFormat = dateFormat;
    }

    public Double getDiscountRate() {
        return discountRate;
    }

    public void setDiscountRate(Double discountRate) {
        this.discountRate = discountRate;
    }

    public int getDiscountedCreditTerm() {
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        return discountedCreditTerm;
    }

    public void setDiscountedCreditTerm(int discountedCreditTerm) {
        this.discountedCreditTerm = discountedCreditTerm;
    }

    public boolean isEditMode() {
        return editMode;
    }

    public void setEditMode(boolean editMode) {
        this.editMode = editMode;
    }

    public InvoiceAndReceiptBeanRemote getInvoiceBean() {
        return invoiceBean;
    }

    public void setInvoiceBean(InvoiceAndReceiptBeanRemote invoiceBean) {
        this.invoiceBean = invoiceBean;
    }

    public Date getInvoiceDueDate() {
        return invoiceDueDate;
    }

    public void setInvoiceDueDate(Date invoiceDueDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("dd/MMM/yyyy");
        invoiceDueDateString = formatter.format(invoiceDueDate);
        this.invoiceDueDate = invoiceDueDate;
    }
    
       public String getInvoiceDueDateString() {
        return invoiceDueDateString;
    }

    public void setInvoiceDueDateString(String invoiceDueDateString) {
        this.invoiceDueDateString = invoiceDueDateString;
    }

    public Long getInvoiceId() {
        return invoiceId;
    }

    public void setInvoiceId(Long invoiceId) {
        this.invoiceId = invoiceId;
    }

    public boolean isInvoiceStatus() {
        return invoiceStatus;
    }

    public void setInvoiceStatus(boolean invoiceStatus) {
        this.invoiceStatus = invoiceStatus;
    }

    public Date getIssueDate() {
        return issueDate;
    }

    public void setIssueDate(Date issueDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("dd/MMM/yyyy");
        issueDateString = formatter.format(issueDate);
        this.issueDate = issueDate;
    }

    public Long getSalesOrderId() {
        return salesOrderId;
    }

    public void setSalesOrderId(Long salesOrderId) {
        this.salesOrderId = salesOrderId;
    }

    public List<SalesDocumentState> getSalesOrders() {
        return salesOrders;
    }

    public void setSalesOrders(List<SalesDocumentState> salesOrders) {
        this.setSalesOrders(salesOrders);
    }

    public InvoiceAndReceiptState getSelectedInvoice() {
        return selectedInvoice;
    }

    public void setSelectedInvoice(InvoiceAndReceiptState selectedInvoice) {
        this.selectedInvoice = selectedInvoice;
    }

    public List<InvoiceAndReceiptState> getSelectedInvoices() {
        return selectedInvoices;
    }

    public void setSelectedInvoices(List<InvoiceAndReceiptState> selectedInvoices) {
        this.selectedInvoices = selectedInvoices;
    }

    public InvoiceAndReceiptState[] getSelectedInvoicesArray() {
        return selectedInvoicesArray;
    }

    public void setSelectedInvoicesArray(InvoiceAndReceiptState[] selectedInvoicesArray) {
        this.selectedInvoicesArray = selectedInvoicesArray;
    }

    public SalesOrderProcessingModuleRemote getSop() {
        return sop;
    }

    public void setSop(SalesOrderProcessingModuleRemote sop) {
        this.sop = sop;
    }

    public Double getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(Double totalPrice) {
        this.totalPrice = totalPrice;
    }

    public Collection<LineEntryEntity> getSelectedProductList() {
        return selectedProductList;
    }

    public void setSelectedProductList(Collection<LineEntryEntity> selectedProductList) {
        this.setSelectedProductList(selectedProductList);
    }

    public String getDeleteFlag() {
        return deleteFlag;
    }

    public void setDeleteFlag(String deleteFlag) {
        this.deleteFlag = deleteFlag;
    }

    public InvoiceAndReceiptState getSelectedViewInvoice() {
        return selectedViewInvoice;
    }

    public void setSelectedViewInvoice(InvoiceAndReceiptState selectedViewInvoice) {
        selectedViewProductList = invoiceBean.getInvoiceLineEntry(selectedViewInvoice.getInvoiceId());
        this.setSelectedViewProductList(selectedViewProductList);
        this.selectedViewInvoice = selectedViewInvoice;
    }

        public void generateInvoiceReport(ActionEvent event) throws ServletException{
                 System.out.println("TRY TO GENERATE REPORT ");
        try
        { 
            if(selectedViewInvoice != null){
            System.out.print("managedbean1");
             Long selectedPrintInvoiceID = selectedViewInvoice.getInvoiceId();
             FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("selectedPrintInvoiceID", selectedPrintInvoiceID);
             FacesContext.getCurrentInstance().getExternalContext().redirect("http://localhost:8181/MerlionERP-war/invoiceServlet");
            System.out.print("managedbean2");
            }else{
               System.out.println("selectedPrintInvoice is null"); 
            }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
        
          public void generateReceiptReport(ActionEvent event) throws ServletException{
                 System.out.println("TRY TO GENERATE REPORT ");
   try
        { 
            if(selectedViewInvoice != null){
                     System.out.print("Selected invoice not null :: generate receipt report");
            System.out.print("managedbean1");
             Long selectedPrintInvoiceID = selectedViewInvoice.getInvoiceId();
             System.out.println("Selected print invoice Id : "+selectedPrintInvoiceID);
             FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("selectedPrintInvoiceID", selectedPrintInvoiceID);
             FacesContext.getCurrentInstance().getExternalContext().redirect("http://localhost:8181/MerlionERP-war/receiptServlet");
            System.out.print("managedbean2");
            }else{
               System.out.println("selectedPrintInvoice is null"); 
            }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
        
    public Collection<InvoiceLineEntryEntity> getSelectedViewProductList() {
        return selectedViewProductList;
    }

    public void setSelectedViewProductList(Collection<InvoiceLineEntryEntity> selectedViewProductList) {
        this.selectedViewProductList = selectedViewProductList;
    }

    public String getIssueDateString() {
        return issueDateString;
    }

    public void setIssueDateString(String issueDateString) {
        this.issueDateString = issueDateString;
    }

    public String getPaymentMethod() {
        return paymentMethod;
    }

    public void setPaymentMethod(String paymentMethod) {
        this.paymentMethod = paymentMethod;
    }

    public List<String> getPaymentMethods() {
        return paymentMethods;
    }

    public void setPaymentMethods(List<String> paymentMethods) {
        this.paymentMethods = paymentMethods;
    }
    
}
